#include "helper.h"
#include "monitor.h"
#include "reg.h"

extern uint32_t in_str;
extern char assembly[80];

/* decode OFF16-type instruction with unsigned immediate */
static void decode_off16_type(uint32_t instr) {

    op_src1->type = OP_TYPE_REG;
    op_src1->reg = (instr >> 5) & 0x0000001F;
    op_src1->val = reg_w(op_src1->reg);

    op_src2->type = OP_TYPE_REG;
    op_src2->reg = instr & 0x0000001F;
    op_src2->val = reg_w(op_src2->reg);

    op_dest->type = OP_TYPE_REG;
    op_dest->simm = (int) (instr & 0x03FFFC00) << 6 >> 14;
}

make_helper(beq) {
    decode_off16_type(in_str);
    if (op_src1->val == op_src2->val) {
        cpu.pc += op_dest->simm;
    }
    sprintf(assembly, "beq\t%s,\t%s,\t0x%04x", REG_NAME(op_src1->reg), REG_NAME(op_src2->reg), op_dest->simm);
}

make_helper(bne) {
    decode_off16_type(in_str);
    if (op_src1->val != op_src2->val) {
        cpu.pc += op_dest->simm;
    }
    sprintf(assembly, "bne\t%s,\t%s,\t0x%04x", REG_NAME(op_src1->reg), REG_NAME(op_src2->reg), op_dest->simm);
}

make_helper(blt) {
    decode_off16_type(in_str);
    if ((int) op_src1->val < (int) op_src2->val) {
        cpu.pc += op_dest->simm;
    }
    sprintf(assembly, "blt\t%s,\t%s,\t0x%04x", REG_NAME(op_src1->reg), REG_NAME(op_src2->reg), op_dest->simm);
}
